#ifndef __HARDWARE_H__
#define __HARDWARE_H__

#include <Arduino.h>

// 调试信息打印开关，不打印则将下行注释掉
//#define DEBUG_ON

#ifdef DEBUG_ON
#define dbLog(prompt) Serial.println(prompt)
#define dbLogValue(prompt, value) \
    Serial.print(prompt);         \
    Serial.println(value, DEC)
#else
#define dbLog(prompt)
#define dbLogValue(prompt, value)
#endif

// #define USE_U8G2 // 要使用u8g2库，将此注释去掉
// #define USE_BatterySense //要使用BatterySense库，将此注释去掉
// #define USE_UCS2 // 使用UCS2储存字符，若直接使用UTF8，将此注释去掉(未实现，不能去掉！)
#define SHOW_VOLTAGE // 电量显示位置直接显示电池电压(用于测试电压与电量关系)

//=================== 以下为硬件引脚定义 =================================
#define SD_CS GPIO_NUM_4  // 4 SD卡片选脚
#define EPD_CS GPIO_NUM_5 // 5 墨水屏显示片选脚

#define WAKE_IO GPIO_NUM_25 // 25 唤醒脚(sd卡读写使能、电池电压测量使能)

#define BEEP_IO GPIO_NUM_26 // 26 蜂鸣器引脚(这是我让制造商专门加了哦！)
#define KEY_UP_IO GPIO_NUM_39       // 39 上键引脚
#define KEY_DN_IO GPIO_NUM_34       // 34 下键引脚(其实是中键，下键是EN键)
#define BATTERY_READ_IO GPIO_NUM_36 // 36 电池电压读取脚

#define WAKE_UP_IO_MASK 0x8400000000 // 唤醒引脚掩码 io34(1<<34),io39(1<<39)

// 墨水屏连接EPS32对应引脚
#define EPD_DC GPIO_NUM_19 // 19
#define EPD_RST GPIO_NUM_16 // 16
#define EPD_BUSY GPIO_NUM_17 // 17

// 要同时使用SD卡和EPD，必须有一个SPI要重映射
#define USE_REMAP_SD_SPI

#ifdef USE_REMAP_SD_SPI
#define REMAP_SD_SPI
#else
#define REMAP_EPD_SPI
#endif

//=================== 以上为硬件引脚定义 =================================

// 屏幕分辨率
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 416

// 黑白颜色定义(居然与GxEPD2的定义相反！)
#define BLACK_COLOR 0xffff
#define WHITE_COLOR 0x0000

// 按键定义，最下键为EN复位键
#define KEY_NL -1 // 非法键
#define KEY_EP 0  // 无按键
#define KEY_UP 1  // 短按上键
#define KEY_BK 2  // 长按上键
#define KEY_DN 3  // 短按下键
#define KEY_MD 4  // 长按下键

// 视图定义
#define VT_NONE 0   // 无
#define VT_CLOCK 1  // 时钟
#define VT_MENU 2   // 主菜单
#define VT_EYE 3    // 视力训练
#define VT_TOMATO 4 // 番茄钟
#define VT_DIR_F 5  // 选取阅读文件
#define VT_DIR_T 6  // 选取词条文件
#define VT_READ 7   // 阅读文件
#define VT_TERM 8   // 词条记忆

#define SD_RETRY_TIME 3 // 读写SD卡重试次数

extern int8_t wakeUpSeconds;
extern uint64_t wakeUpIOMask;

/**
 * @brief 读取用户按键
 * @return 0:无按键 1:短按中键 2:长按中键 3:短按右键 4:长按右键
 * =======================================
 * 按键    上   下   EN   长按  上   下  EN
 * ---------------------------------------
 * 主菜单  <    >            返回
 * 列目录  <    >            返回  选中
 * 番茄钟  <    >            返回  开始
 * 练视力                    返回
 * 阅读    <    >            返回
 * 记忆  不会   会了         返回
 * =======================================
 */
uint8_t getKey();

/**
 * @brief 装载SD卡
 * @param bool side true: 装载 false: 卸载
 * @return 返回装载状态 true 已装载，false 已卸载
 */
bool sdMount(bool side);

#ifndef USE_BatterySense
/**
 * 读锂电池电量级别
 * @return 0-5, 0 没电， 5 满电
*/
int batteryLevel();
#endif

/**
 * @brief 重置IO口以减少电量消耗
 */
void gpioResetPins();

#endif